package com.melon.handler;

import com.melon.entity.PowerAssistServiceInfoVM;
import com.melon.http.PowerAssistRemoteHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author TianGua
 * @since 2024/10/17 - 13:47
 */
@Component
@Slf4j
public class PowerAssistHandler {

    @Autowired
    private PowerAssistRemoteHandler powerAssistRemoteHandler;

    public PowerAssistServiceInfoVM getOwnerServiceInfo() {
        String appId = getAppId();
        if(StringUtils.isBlank(appId)) {
            log.info("【getOwnerServiceInfo】appId is null.");
            return null;
        }

        String appSecret = getAppSecret();
        if(StringUtils.isBlank(appSecret)) {
            log.info("【getOwnerServiceInfo】appSecret is null.");
            return null;
        }

        return powerAssistRemoteHandler.getAppServiceInfo(appId, appSecret);
    }


    public String getAppId() {
        return System.getenv("APP_ID");
    }

    public String getAppSecret() {
        return System.getenv("APP_SECRET");
    }

    public Boolean assist(Integer type, Integer count) {
        String appId = getAppId();
        if(StringUtils.isBlank(appId)) {
            log.info("【assist】appId is null.");
            return null;
        }

        String appSecret = getAppSecret();
        if(StringUtils.isBlank(appSecret)) {
            log.info("【assist】appSecret is null.");
            return null;
        }

        if(Objects.equals(type, 1)) {
            powerAssistRemoteHandler.expand(appId, appSecret, count);
        } else if(Objects.equals(type, 2)) {
            powerAssistRemoteHandler.contract(appId, appSecret, count);
        } else {
            log.info("【assist】unknown type.");
        }

        return Boolean.TRUE;
    }

//    public Boolean assist(String type, Double threshold) {
//        PowerAssistServiceInfoVM ownerServiceInfo = getOwnerServiceInfo();
//        if(Objects.isNull(ownerServiceInfo)) {
//            log.info("【Power Assist】ownerServiceInfo is null.");
//            return Boolean.FALSE;
//        }
//
//        List<PowerAssistServiceInfoVM.ContainerInfoVM> containerList = ownerServiceInfo.getContainerList();
//        if(CollectionUtils.isEmpty(containerList)) {
//            log.info("【Power Assist】containerList is empty.");
//            return Boolean.FALSE;
//        }
//
//        List<PowerAssistServiceInfoVM.ContainerInfoVM> commonContainerList = getCommonContainerList(containerList);
//        if(CollectionUtils.isEmpty(commonContainerList)) {
//            log.info("【Power Assist】commonContainerList is empty.");
//            return Boolean.FALSE;
//        }
//
//        Double totalContainersMetric = 0d;
//
//        Double totalCommonContainersMetric = 0d;
//
//        Integer totalContainerCount = containerList.size();
//
//        Integer runningContainerCount = containerList.size();
//
//        Integer runningCommonContainerCount = commonContainerList.size();
//
//
//        for (PowerAssistServiceInfoVM.ContainerInfoVM container : containerList) {
//            if(Objects.isNull(container)) {
//                log.info("【Power Assist】container is null.");
//                continue;
//            }
//
//            String appId = container.getAppId();
//            if(StringUtils.isBlank(appId)) {
//                log.info("【Power Assist】appId is null.");
//                continue;
//            }
//
//            PowerAssistServiceInfoVM.ContainerMetricVM metric = container.getMetric();
//            if(Objects.isNull(metric)) {
//                log.info("【Power Assist】metric is null.");
//                continue;
//            }
//
//            log.info("【Power Assist】the container's metric info = [{}], appId = [{}]", metric, appId);
//
//            //如果指标不存在，减少运行中的容器数量
//            Boolean isCommonContainer = !Objects.equals(container.getDeploySource(), 4);
//            if(!"running".equals(metric.getStatus())) {
//                if(isCommonContainer) {
//                    runningCommonContainerCount--;
//                }
//
//                runningContainerCount--;
//            } else {
//                //获取容器当前指标
//                double metricValue = getMetricValue(metric, type);
//                if(isCommonContainer) {
//                    totalCommonContainersMetric += metricValue;
//                }
//
//                totalContainersMetric += metricValue;
//            }
//        }
//
//        if(runningContainerCount <= 0 || runningCommonContainerCount <= 0) {
//            log.info("【Power Assist】runningContainerCount or runningCommonContainerCount = 0.");
//            return Boolean.FALSE;
//        }
//
//        double serviceMetricNow = totalContainersMetric / runningContainerCount;
//        log.info("【Power Assist】服务当前指标 = [{}], 阈值 = [{}],", serviceMetricNow, threshold);
//
//        if(serviceMetricNow > threshold) {
//
//            Integer expandCount = getExpandCount(totalContainerCount, runningContainerCount, totalContainersMetric, threshold, serviceMetricNow);
//            if(expandCount > 0) {
//
//            }
//
//
//        }
//
//
//
//
//
//
//
//        List<PowerAssistServiceInfoVM.ContainerInfoVM> runningContainerList = containerList.stream().filter(record -> StringUtils.isNotBlank(record.getStatus()))
//                .filter(record -> StringUtils.equals(record.getStatus(), "running"))
//                .collect(Collectors.toList());
//        if(CollectionUtils.isEmpty(runningContainerList)) {
//            log.info("【Power Assist】running container list is empty.");
//            return Boolean.FALSE;
//        }
//
//
//    }

    private Integer getExpandCount(Integer totalContainerCount, Integer runningContainerCount, Double threshold, Double serviceMetricNow, double metricNow) {
        //1、计算未运行的容器数量
        int notRunningContainerCount = totalContainerCount - runningContainerCount;

        //3、如果平均指标超过阈值，表示需要扩容
        if (serviceMetricNow > threshold) {
            //4、计算需要的容器总数，并加上未运行的容器数量
            int needTotalContainer = calculateNeededContainers(serviceMetricNow, threshold, runningContainerCount) + notRunningContainerCount;

            //5、计算最终需要扩展的容器数量
            return calculateExpandCount(needTotalContainer, totalContainerCount);
        }

        // 如果不需要扩容，返回 0
        return 0;
    }

    private int calculateExpandCount(int needTotalContainer, int totalContainerCount) {
        // 计算最终的扩容数量，保证不会小于 0
        return Math.max(needTotalContainer - totalContainerCount, 0);
    }

    private int calculateNeededContainers(double averageIndex, double threshold, int runningContainerCount) {
        return new BigDecimal(averageIndex / threshold * runningContainerCount)
                .setScale(0, RoundingMode.UP)
                .intValue();
    }

    private double getMetricValue(PowerAssistServiceInfoVM.ContainerMetricVM metricInfo, String metricType) {
        if (metricInfo == null) {
            return 0d;
        }
        if ("CPU".equals(metricType)) {
            if (metricInfo.getCpuUsage() == null) {
                return 0d;
            }

            if(metricInfo.getCpuUsage().has("total") && metricInfo.getCpuUsage().has("cores")) {
                double totalUsage = metricInfo.getCpuUsage().get("total").asDouble();

                Integer coresLength = getCoresLength(metricInfo.getCpuUsage().get("cores").toString());
                if(Objects.isNull(coresLength)) {
                    return 0;
                }

                return totalUsage / coresLength;
            }

            return 0d;
        } else {
            if (metricInfo.getMemoryUsage() == null || metricInfo.getMemoryLimit() == null || metricInfo.getMemoryLimit() == 0) {
                return 0d;
            } else {
                return (metricInfo.getMemoryUsage().doubleValue() / metricInfo.getMemoryLimit()) * 100;

            }
        }
    }

    private Integer getCoresLength(String coresMetric) {
        // 1. 去除字符串首尾的中括号
        String trimmedStr = coresMetric.substring(1, coresMetric.length() - 1);
        if(StringUtils.isBlank(trimmedStr)) {
            return 0;
        }

        // 2. 使用逗号作为分隔符分割字符串
        String[] stringArray = trimmedStr.split(",");

        return stringArray.length;
    }

    private List<PowerAssistServiceInfoVM.ContainerInfoVM> getCommonContainerList(List<PowerAssistServiceInfoVM.ContainerInfoVM> containerList) {
        List<PowerAssistServiceInfoVM.ContainerInfoVM> collect = containerList.stream()
                .filter(record -> Objects.nonNull(record.getDeploySource()))
                .filter(record -> !Objects.equals(record.getDeploySource(), 4))
                .collect(Collectors.toList());

        return collect;
    }
}
